home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DClap / DChildApp.cpp < prev    next >
Text File  |  1996-07-05  |  20KB  |  857 lines

  1. // DChildApp.cpp
  2.  
  3.  
  4. #include "DClap.h"
  5. #include "DChildApp.h"
  6.  
  7.  
  8. // for DChildDlogDoc
  9. #include "Dvibrant.h"
  10. #include "DWindow.h"
  11. #include "DNetObject.h"
  12. #include "DURL.h"
  13. #include "DRichMoreStyle.h"
  14. #include "DBOPclient.h"
  15.  
  16.  
  17. #undef DEBUG
  18.  
  19.  
  20.  
  21. #ifdef WIN_MAC
  22.     // undef some conflicts b/n Types.h && NlmTypes
  23. #undef Handle
  24. //#undef true
  25. //#undef false
  26. //#undef Boolean
  27. #include <AppleEvents.h>
  28. #include <Processes.h>
  29. //#define Boolean  Nlm_Boolean
  30. #endif
  31.  
  32. #ifdef WIN_MSWIN
  33. #include <windows.h>
  34. #include <windowsx.h>
  35. #endif
  36.  
  37. //class DChildFile : public DFile
  38.  
  39.  
  40. DChildFile::DChildFile( const char* filename, short kind,
  41.     Boolean deleteWhenDone,
  42.     short doneAction, const char* openmode, 
  43.     const char* ftype, const char* fcreator) :
  44.     DFile( filename, openmode, ftype, fcreator),
  45.     fAction(doneAction), fKind(kind), fDelete( deleteWhenDone)
  46. {
  47.     //fName2= StrDup(filename); // fix probs w/ fName getting corrupted !!!!???
  48.     if (!openmode) switch (fKind) {
  49.         case kInput: 
  50.         case kStdin:  fMode= StrDup("r"); break;    //?? we really open "w" not "r" ??
  51.         default:
  52.         case kOutput: fMode= StrDup("r"); break;  //?? we really open "r" not "w" !? 
  53.         case kStdout: fMode= StrDup("r"); break;  // was "a", ??? "w" or "a"
  54.         case kStderr: fMode= StrDup("r"); break;  // was "a", ??? "w" or "a"
  55.         }
  56. }
  57.  
  58. DChildFile::~DChildFile()
  59. {
  60.     MemFree(fName2);
  61. #ifndef DEBUG
  62.     if (fDelete) this->Delete();
  63. #endif
  64. }
  65.  
  66. void DChildFile::ClearStorage()
  67. {
  68.     this->Close();
  69. #ifndef DEBUG
  70.     if (fDelete) this->Delete();
  71. #endif
  72. }
  73.  
  74.  
  75.  
  76.  
  77.  
  78. //class DChildApp : public DTaskMaster
  79.     
  80. DChildApp::DChildApp() :     
  81.     DTaskMaster(0),
  82.     fName(NULL), fCmdline(NULL), 
  83.     fStdin(NULL), fStdout(NULL), fStderr(NULL),
  84.     fLaunched(0), fResult(0), fReusable(false), fCallMethod(kNone),
  85.     fProcessNum(0), fFiles(NULL), fNob(NULL), fBopper(NULL)
  86. {
  87.   if (!DChildAppManager::gChildList) DChildAppManager::gChildList= new DList();
  88.     DChildAppManager::gChildList->InsertLast( this); // do this here so caller doesn't forget
  89. }
  90.  
  91.  
  92. DChildApp::DChildApp( char* appname, char* cmdline, 
  93.     Boolean showStdout, char* Stdinfile, Boolean showStderr)  :  
  94.     DTaskMaster(0),
  95.     fName(NULL), fCmdline(NULL), 
  96.     fStdin(NULL), fStdout(NULL), fStderr(NULL),
  97.     fLaunched(0), fResult(0), fReusable(false), fCallMethod(kNone),
  98.     fProcessNum(0), fFiles(NULL), fNob(NULL), fBopper(NULL)
  99. {
  100.     fName= StrDup( appname);
  101.     fCmdline= StrDup( cmdline);
  102.     
  103.     //fFiles= new DList();
  104.  
  105.     // this is called for launching docs as well as apps,
  106.     // don't do the stdout/stderr stuff if this is doc
  107.     if (showStdout) AddFile( DChildFile::kStdout, NULL);
  108.     if (showStderr) AddFile( DChildFile::kStderr, NULL);
  109.     if (Stdinfile) AddFile( DChildFile::kStdin, Stdinfile);
  110.     
  111.   if (!DChildAppManager::gChildList) DChildAppManager::gChildList= new DList();
  112.     DChildAppManager::gChildList->InsertLast( this); // do this here so caller doesn't forget
  113. }
  114.  
  115.  
  116. DChildApp::~DChildApp()
  117. {
  118.     ClearFiles();
  119.     if (fFiles) delete fFiles; fFiles= NULL;
  120.     MemFree( fName);
  121.     MemFree( fCmdline);
  122.     if (fNob) delete fNob;
  123.     if (fBopper) delete fBopper;
  124.     DChildAppManager::gChildList->Delete( this); //need here to balance constructor Insert()
  125. }
  126.  
  127. void DChildApp::ClearFiles()
  128. {
  129.     if (fFiles) {
  130.         short i, n= fFiles->GetSize();
  131. #if 0
  132.             // ?? is this causing trashed DChildFiles ??
  133.         for (i=n-1; i>=0; i--) {
  134.             DChildFile* afile= (DChildFile*) fFiles->At(i);
  135.             delete afile;
  136.             }
  137. #endif
  138. #if 1
  139.         fFiles->DeleteItemsAt(0,n);
  140. #else
  141.         delete fFiles; fFiles= NULL;
  142. #endif
  143.         }
  144. }
  145.  
  146.  
  147. void DChildApp::AddInputBuffer( short filekind, char* buffer, ulong buflen)
  148. {
  149.     char    namestore[512], *name;
  150.     DChildFile* aFile;
  151.     name= gFileManager->TempFilename(namestore);
  152.     switch (filekind) {
  153.         case DChildFile::kInput: 
  154.         case DChildFile::kStdin:  
  155.             aFile= new DChildFile( name, filekind, true, DChildFile::kNoAction);
  156.             break;
  157.         default:
  158.             return;
  159.         }
  160.     if (aFile) {
  161.         aFile->Open("w");
  162.         aFile->WriteData( buffer, buflen);
  163.         aFile->Close();
  164.         aFile->SetMode("r");
  165.         this->AddFile( aFile);
  166.         }
  167. }
  168.  
  169. void DChildApp::AddFile( DChildFile* aFile)
  170. {
  171.         // ?? need to check if fFiles already has one of stdio types ??
  172.     if (!fFiles)     fFiles= new DList();
  173.     fFiles->InsertLast( aFile);
  174.     switch (aFile->fKind) {
  175.         case DChildFile::kStdin:  
  176.             fStdin= aFile->GetName();
  177.             break;
  178.         case DChildFile::kStdout:  
  179.             fStdout= aFile->GetName();
  180.             break;
  181.         case DChildFile::kStderr:  
  182.             fStderr= aFile->GetName();
  183.             break;
  184.         }
  185. }
  186.  
  187. void DChildApp::AddFile( short filekind, char* name)
  188. {
  189.     char    namestore[512];
  190.     DChildFile* aFile;
  191.     if (!name) {
  192.         if (filekind == DChildFile::kStdin || filekind == DChildFile::kInput) return;
  193.         name= gFileManager->TempFilename(namestore);
  194.       }
  195.       
  196.     switch (filekind) {
  197.         case DChildFile::kInput: 
  198.         case DChildFile::kStdin:  
  199.             aFile= new DChildFile( name, filekind, false, DChildFile::kNoAction);
  200.             break;
  201.         
  202.         default:
  203.         case DChildFile::kOutput:   
  204.         case DChildFile::kStdout:  
  205.             aFile= new DChildFile( name, filekind, false);
  206.             break;
  207.         case DChildFile::kStderr:  
  208.             aFile= new DChildFile( name, filekind, true);
  209.             break;
  210.         }
  211.     this->AddFile( aFile);
  212.  
  213.  
  214.  
  215. #ifdef WIN_MAC
  216. extern "C" ProcessSerialNumber  gChildProcessSN;
  217. #else
  218. extern "C" long gChildProcessSN;
  219. #endif
  220.  
  221. enum { kChildTask = 3245, kStatusTask = 34382 };
  222.  
  223. class DBurialTask : public DTask {
  224. public:
  225.     DBurialTask( long processnum, DTaskMaster* itsSource) :
  226.         DTask( processnum, kChildTask, itsSource) {}
  227.     virtual void DoIt() { DChildAppManager::BuryDeadChildApp(fNumber); }
  228. };
  229.  
  230. class DStatusTask : public DTask {
  231. public:
  232.     DStatusTask() :
  233.         DTask( DChildAppManager::kStatusTask, DChildAppManager::kChildManagerTask, 
  234.                     gChildAppManager) 
  235.         {
  236.         if (!gTaskCentral->FindTask(this)) fRepeat= true;
  237.         }
  238.     virtual void DoIt() { 
  239.         //if (!DChildAppManager::CheckStatus()) fRepeat= false;
  240.         }
  241. };
  242.  
  243.  
  244. Boolean DChildApp::Launch()
  245. {
  246.     fResult= 0;
  247.     gCursor->watch();
  248.     switch (fCallMethod) {
  249.         case kLocalexec:
  250.             (void) LaunchLocal();
  251.             break;
  252.         case kBOPexec:
  253.             (void) LaunchBop();
  254.             break;
  255.         case kHTTPget:
  256.         case kHTTPpost:
  257.         default:
  258.             break;
  259.         }    
  260.     gCursor->arrow();
  261.     return  fResult;
  262. }
  263.  
  264.  
  265. Boolean DChildApp::LaunchBop()
  266. {
  267.     char * aHost, * aUser, * aPass, * aPath;
  268.     long    aPort;
  269.     fResult= 0;
  270.     
  271.     if (!fNob) fNob = new DNetOb();
  272.     if (!DURL::ParseURL( fNob, fName)) ; // ?? error
  273.     aHost= (char *)fNob->GetHost(); if (!aHost||!*aHost) aHost= DBOP::gHost;
  274.     aPort= fNob->fPort;  if (!aPort) aPort= DBOP::gPort;
  275.     aPath= (char *)fNob->GetPath();
  276.  
  277.     //if (!aHost || (!aPath && !fCmdline)) return fResult;
  278.     if ((!aPath && !fCmdline)) return fResult;
  279.  
  280.     aUser= (char *)fNob->GetUser(); if (!aUser||!*aUser) aUser= DBOP::gUsername;
  281.     aPass= (char *)fNob->GetPass(); if (!aPass||!*aPass) aPass= DBOP::gPassword;
  282.     
  283.     if (!fBopper) fBopper= new DBOP( aUser, aPass, aHost, aPort);
  284.     else fBopper->ResetHost( aUser, aPass, aHost, aPort);
  285.  
  286.     if (*aPath == '/') aPath++; // default / is leftover from URL syntax
  287.     long len= 2 + StrLen(aPath) + StrLen(fCmdline);
  288.     char* cmdline = (char*) MemNew( len);
  289.     *cmdline= 0;
  290.     if (aPath) { 
  291.         StrCat( cmdline, aPath);
  292.         StrCat( cmdline, " ");
  293.         }
  294.     if (fCmdline) StrCat( cmdline, fCmdline);
  295.     fLaunched++;
  296.     fResult= fBopper->Execute( cmdline, fFiles);
  297.     fProcessNum= fBopper->ProcessNum();
  298.     MemFree( cmdline);
  299.     
  300.     if (fProcessNum) {
  301.         // ?? save user/pass from fBopper (which can ask for new)??
  302.         if (!StrCmp(fBopper->GetUser(),fNob->GetUser()))
  303.             fNob->StoreUser( (char*)fBopper->GetUser());
  304.         if (!StrCmp(fBopper->GetPass(),fNob->GetPass()))
  305.             fNob->StorePass( (char*)fBopper->GetPass());
  306.         if (!StrCmp(fBopper->GetHost(),fNob->GetHost()))
  307.             fNob->StoreHost( (char*)fBopper->GetHost());
  308.         if ( fBopper->gPort != fNob->fPort)
  309.             fNob->fPort= fBopper->gPort;
  310.         }
  311.     
  312.     DStatusTask* statme = new DStatusTask();
  313.     PostTask( statme);
  314.          
  315.     return fResult;
  316. }
  317.     
  318.  
  319. Boolean DChildApp::LaunchLocal()
  320. {
  321.         // ?? want special handling for stdin/stdout/stderr files !!
  322.         // !! must assume OtherFiles are already handled, either in cmdline or by child app !!
  323.     fResult= 0;
  324.     
  325.     if (fName || fCmdline) {
  326.         fLaunched++;
  327.         fResult= Dgg_LaunchApp( fName, fCmdline, (char*)fStdin, 
  328.                                     (char*)fStdout, (char*)fStderr);
  329.  
  330.         if (fResult) {
  331. #ifdef WIN_MAC
  332.             fProcessNum= (long) MemNew(sizeof(ProcessSerialNumber));
  333.             *((ProcessSerialNumberPtr) fProcessNum)= gChildProcessSN;
  334. #else
  335.             fProcessNum= gChildProcessSN;
  336. #endif
  337.  
  338. #ifdef WIN_MSWIN
  339. #ifdef WIN16
  340.             // assume no multiprocessing?? 
  341.             DBurialTask* buryMe = new DBurialTask( gChildProcessSN, this);
  342.             PostTask( buryMe);
  343. #else
  344.             DStatusTask* statme = new DStatusTask();
  345.             PostTask( statme);
  346. #endif
  347. #endif
  348.             //gChildList->InsertLast( this); // done in constructor;
  349.             // can we assume only one copy of this in list ??
  350.             } 
  351.         }
  352.     return fResult;
  353. }
  354.  
  355.  
  356.  
  357. void DChildApp::FileAction(DChildFile* aFile)
  358. {
  359.     switch (aFile->fAction) {
  360.       case DChildFile::kOpenPict:
  361.         case DChildFile::kOpenText: 
  362.             gApplication->OpenDocument( aFile);
  363.             if (aFile->fDelete) {
  364.                 DWindow* win= gWindowManager->CurrentWindow();
  365.                 if (win && win->fSaveHandler) win->fSaveHandler->Dirty();
  366.                 }
  367.             break;
  368.             
  369.         default:
  370.             break;
  371.         }
  372. }
  373.  
  374. void DChildApp::Finished()
  375. {
  376.     fLaunched--; // ?? or use this as counter?
  377.     gCursor->watch();
  378.     if (fCallMethod == kBOPexec && fBopper) {
  379.         fBopper->GetOutput( fProcessNum, fFiles);
  380.         fBopper->Delete( fProcessNum);
  381.         fBopper->Quit(); // ??
  382.         }
  383.     if (fFiles) {
  384.         DChildFile* aFile;
  385.         short i, n= fFiles->GetSize();
  386.         for (i=n-1; i>=0; i--) {
  387.             aFile= (DChildFile*) fFiles->At(i);
  388.             if (aFile->Exists() && aFile->LengthF()>0) 
  389.                 FileAction( aFile);
  390.             aFile->ClearStorage();
  391.             }
  392.         ClearFiles();
  393.         }
  394.     gCursor->arrow();
  395. }
  396.  
  397.  
  398.  
  399. // class DExternalHandler : public DChildApp
  400.  
  401. DExternalHandler::DExternalHandler( char* cmdlineOrDocname) :
  402.     DChildApp( cmdlineOrDocname, NULL, false, NULL, false)
  403. {
  404. }
  405.  
  406. Boolean DExternalHandler::Launch()
  407. {
  408.     return DChildApp::Launch();
  409. }
  410.  
  411. void DExternalHandler::Finished()
  412. {
  413.     DChildApp::Finished();
  414. }
  415.             
  416.  
  417.  
  418.  
  419.  
  420. // class DChildAppManager : public DObject
  421.  
  422.  
  423. //static
  424. DList* DChildAppManager::gChildList = NULL; // new DList(); << bad on SGI // of DChildApp
  425. long DChildAppManager::gLastTime = 0;
  426.  
  427. DChildAppManager* gChildAppManager = new DChildAppManager();
  428.  
  429. enum { 
  430. #ifdef WIN_MAC
  431.     kStatDelay = 1200 // 60ths of second to minutes
  432. #endif
  433. #ifdef WIN_MSWIN
  434.     kStatDelay = 10000 // milliseconds to minutes 
  435. #endif
  436. #ifdef WIN_MOTIF
  437.     kStatDelay = 1200 //  60ths of second to minutes 
  438. #endif
  439.     };
  440.  
  441. DChildAppManager::DChildAppManager() :
  442.     DTaskMaster( kChildManagerTask)
  443. {
  444. }
  445.  
  446.  
  447. Boolean DChildAppManager::IsMyTask(DTask* theTask)
  448. {
  449.   if (theTask && theTask->fNumber == kStatusTask) { 
  450.     short stat= CheckStatus();
  451.     theTask->fRepeat= (stat != 0);
  452.    }
  453.   return true;
  454. }
  455.  
  456.  
  457. //static
  458. short DChildAppManager::BuryDeadChildApp( long theEvent)
  459. {
  460. #ifdef WIN_MAC
  461.     short         err;
  462.     long             appErr;
  463.     Size            actualSize;
  464.     ProcessSerialNumber appSN;
  465.     DescType     returnedType;
  466.      AppleEvent* theAppleEvent;
  467.      
  468.      if (theEvent) {
  469.      theAppleEvent = (AppleEvent*) theEvent;
  470.  
  471.     err= ::AEGetParamPtr( theAppleEvent, keyErrorNumber, typeLongInteger, 
  472.                                                 &returnedType, &appErr, sizeof(appErr), &actualSize);
  473.     if (appErr == 0) { 
  474.         err = AEGetParamPtr( theAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, 
  475.                                                     &returnedType, &appSN, sizeof(appSN), &actualSize);
  476.         Boolean match;
  477.         DChildApp* child= NULL;
  478.         short i, n= gChildList->GetSize();
  479.         for (i=0, match= false; !match && i<n; i++) {
  480.             child= (DChildApp*) gChildList->At(i);
  481.             err= ::SameProcess( (ProcessSerialNumberPtr)child->fProcessNum, &appSN, &match);
  482.             }
  483.             
  484.         if (match) {
  485.             child->Finished();
  486.             //gChildList->Delete(child); // done by child destructor
  487.             if (!child->fReusable) delete child; 
  488.             }
  489.      }
  490.      }
  491. #endif
  492.  
  493. #if defined(WIN_MOTIF) || defined(WIN_MSWIN)
  494.     // use unix(?) signals
  495.     Boolean match;
  496.     DChildApp* child= NULL;
  497.     short i, n= gChildList->GetSize();
  498.     for (i=0, match= false; !match && i<n; i++) {
  499.         child= (DChildApp*) gChildList->At(i);
  500.         match= (child->fProcessNum == theEvent);
  501.         }
  502.     if (match) {
  503.         child->Finished();
  504.         //gChildList->Delete(child); // done by child destructor
  505.         if (!child->fReusable) delete child; 
  506.         }
  507. #endif
  508.     return 0;
  509. }
  510.  
  511.  
  512. //static
  513. Boolean DChildAppManager::CheckStatus()
  514. {    
  515.     short i, n = gChildList->GetSize();
  516.     long now= gUtil->time();
  517.     if (now - gLastTime > kStatDelay) {
  518.         gLastTime= now;
  519.         for (i=n-1; i>=0; i--) {
  520.             DChildApp* child= (DChildApp*) gChildList->At(i);
  521.             if (child && child->fProcessNum) {
  522.             
  523.                 if (child->fCallMethod == DChildApp::kLocalexec) {
  524. #ifdef WIN_MSWIN
  525. #ifndef WIN16
  526.               long waitresult= ! WAIT_TIMEOUT;
  527.               HANDLE hobj= OpenProcess( SYNCHRONIZE, false, child->fProcessNum);
  528.               if (hobj) waitresult= WaitForSingleObject( hobj, 0);
  529.               if (waitresult != WAIT_TIMEOUT) {
  530.                   child->Finished();
  531.                     if (!child->fReusable) delete child; 
  532.                   n--;
  533.                 }
  534. #endif
  535. #endif
  536.                     }
  537.                 else if (child->fCallMethod == DChildApp::kBOPexec && child->fBopper) {
  538.                     if (child->fBopper->CheckStatus(child->fProcessNum)
  539.                                 >= DBOP::kProcDone) {
  540.                   child->Finished();
  541.                     if (!child->fReusable) delete child; 
  542.                   n--;
  543.                         }
  544.                     }
  545.           }
  546.             else n--; //??
  547.             }
  548.         }
  549.     return (n > 0);
  550. }
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557. #include "DChildDlogDoc.h"
  558. #include "DRichViewNu.h"
  559. #include "DRichMoreStyle.h"
  560. #include "DHTMLHandler.h"
  561.  
  562. class    DChildDlogView : public DRichView {
  563. public:
  564.     Boolean fhasVscroll;
  565.     short fPixwidth, fPixheight;
  566.     
  567.     DChildDlogView(long id, DView* itsSuperior, short pixwidth, short pixheight, 
  568.                                     Boolean hasVscroll = true);
  569.     virtual void ReadyToOpen();
  570.     virtual void ShowFile( char* filename, Nlm_FonT font);
  571.     virtual void ShowDoc( char* doctext, ulong doclength = 0);
  572.     virtual void Click( Nlm_PoinT mouse);
  573.     virtual DList* GetControlObjects();
  574. };
  575.  
  576.  
  577.  
  578. DChildDlogView::DChildDlogView(long id, DView* itsSuperior, short pixwidth, short pixheight, 
  579.                                                     Boolean hasVscroll) :
  580.         DRichView( id, itsSuperior, pixwidth, pixheight, hasVscroll )
  581. {
  582.     fhasVscroll= hasVscroll;
  583.     fPixwidth= pixwidth;
  584.     fPixheight= pixheight;
  585. }
  586.  
  587. void DChildDlogView::Click( Nlm_PoinT mouse)
  588. {
  589.     // eat dlog richtext clicks other than to controls !
  590. }
  591.  
  592.  
  593. void  DChildDlogView::ShowFile( char* filename, Nlm_FonT font) 
  594. {
  595.     fDocFormat= DRichHandler::kUnknownformat;
  596.   DHTMLHandler htmlhandler( this, NULL);
  597.   if ( htmlhandler.ProcessFile( filename) ) 
  598.       fDocFormat= htmlhandler.Format(); 
  599.   else {
  600.       DRichHandler texthandler( this, NULL);
  601.       if ( texthandler.ProcessFile( filename) ) 
  602.           fDocFormat= texthandler.Format(); 
  603.       }
  604. }
  605.  
  606.  
  607. void  DChildDlogView::ShowDoc( char* doctext, ulong doclength) 
  608. {
  609.     if (!doctext) return;
  610.     if (!doclength) doclength= StrLen( doctext);
  611.     char*    docend= doctext + doclength;
  612.     
  613.     fDocFormat= DRichHandler::kUnknownformat;
  614.   DHTMLHandler htmlhandler( this, NULL);
  615.      if (htmlhandler.ProcessData( doctext, docend, true, doclength))
  616.       fDocFormat= htmlhandler.Format(); 
  617.   else {
  618.       DRichHandler texthandler( this, NULL);
  619.          if ( texthandler.ProcessData( doctext, docend, true, doclength))
  620.           fDocFormat= texthandler.Format(); 
  621.       }
  622. }
  623.  
  624. void  DChildDlogView::ReadyToOpen()
  625. {
  626.     SetSlateBorder( false);
  627.     SetResize( DView::matchsuper, DView::relsuper);  
  628.     SizeToSuperview( this, true, false);  
  629.     Disable(); //! make so only control items are clickable !! (need for mwin)
  630. }
  631.  
  632.  
  633. DList* DChildDlogView::GetControlObjects()
  634.     DList* controls= new DList();
  635.     short i, n= fStyles->GetSize();
  636.     for (i=0; i<n; i++) {
  637.         DRichStyle* st= (DRichStyle*) fStyles->At(i);
  638.         if (st->fObject 
  639.             && st->fObject->fKind >= DControlStyle::kControlKindStart
  640.             && st->fObject->fKind <= DControlStyle::kControlKindEnd) {
  641.                 controls->InsertLast(st->fObject);
  642.             }
  643.         }
  644.     return controls;
  645. }
  646.  
  647.  
  648.  
  649.  
  650. //class    DChildDlogDoc : public DWindow
  651.  
  652. extern "C" void Nlm_SetRect (Nlm_GraphiC a, Nlm_RectPtr r);
  653. extern "C" void Nlm_GetRect (Nlm_GraphiC a, Nlm_RectPtr r);
  654.  
  655.  
  656. DChildDlogDoc::DChildDlogDoc( long id, Boolean freeOnClose, Nlm_FonT itsFont) :
  657.         DWindow( id, gApplication, document, -5, -5, -50, -20, NULL, freeOnClose), 
  658.         fDlog(NULL), fControls(NULL)
  659. {     
  660.     Nlm_PoinT nps;
  661.     short width, height;
  662.     Nlm_RecT  r;
  663.     
  664.     fFont= itsFont;
  665.     this->GetNextPosition( &nps);
  666.     nps.x= 0; // fix for odd offset
  667.     this->SetNextPosition( nps);
  668.     gUtil->screensize(width, height);
  669.     width = MAX(250, MIN(width-60,gPrintManager->PageWidth()-100));
  670.     height= MIN(350, height-60);
  671.     fDlog= new DChildDlogView( 0, this, width, height, false);
  672.     
  673.     Nlm_GraphiC nwin= (Nlm_GraphiC)this->fNlmObject;
  674.     Nlm_GetRect( nwin, &r);
  675.     r.bottom= height + 5; // + Nlm_vScrollBarWidth; 
  676.     r.right= width + 5; //+ Nlm_hScrollBarHeight;
  677.     Nlm_SetRect( nwin, &r);
  678. }
  679.  
  680.  
  681. DChildDlogDoc::~DChildDlogDoc()
  682. {
  683.     delete fControls;
  684. }
  685.  
  686. void DChildDlogDoc::AddSubordinate(DTaskMaster* subordinate)
  687. {
  688.     DWindow::AddSubordinate(subordinate);
  689. #if 0
  690.     if (subordinate->fId >= DControlStyle::kControlKindStart 
  691.         && subordinate->fId <= DControlStyle::kControlKindEnd) {
  692.         if (!fControls) fControls= new DList();
  693.         fControls->InsertLast(subordinate);
  694.         }
  695. #endif
  696. }
  697.  
  698.  
  699. DList* DChildDlogDoc::GetControls()
  700. {
  701.     if (!fControls) fControls= fDlog->GetControlObjects();
  702.     return fControls;
  703. }
  704.  
  705.  
  706. Nlm_Boolean DChildDlogDoc::PoseModally() 
  707.     if (!IsVisible()) Open(); // already open !?
  708.     fModal = true;
  709.     while (fModal)  
  710.         gApplication->ProcessTasks();  
  711.     return fOkay; // ?? ain't what we want - want fSubordinate's fId
  712. }
  713.  
  714.                               
  715.  
  716. void DChildDlogDoc::OpenText( char* doctext, ulong doclength)
  717. {
  718.     if (doctext) {
  719.         fDlog->ShowDoc( doctext, doclength);
  720.         Open();
  721.         }
  722. }
  723.  
  724. void DChildDlogDoc::Open( DFile* aFile)
  725. {
  726.     if (aFile) {
  727.         SetTitle( (char*)aFile->GetShortname());
  728.         SetFilename( (char*)aFile->GetName());
  729.         fDlog->ShowFile( (char*)aFile->GetName(), fFont);
  730.         }
  731.     Open();
  732. }
  733.  
  734. void  DChildDlogDoc::Open( char* filename) 
  735. {
  736.     SetTitle( (char*)DFileManager::FilenameFromPath(filename));
  737.     SetFilename( (char*) filename);
  738.     fDlog->ShowFile( filename, fFont);
  739.   Open();
  740. }
  741.  
  742. void DChildDlogDoc::Close()
  743. {
  744.     DWindow::Close();
  745. }
  746.  
  747. void DChildDlogDoc::CloseAndFree() 
  748.     fModal= false;
  749.     if (this != gWindowManager->GetAppWindow()) {
  750.         gWindowManager->DeleteWindow(this, false);  
  751.         //fFreeOnClose= true; //<< !!! NO NO NO NO - crash in XWin at least !
  752.         this->Close(); 
  753.         }
  754. }
  755.  
  756. void DChildDlogDoc::ResizeWin()
  757. {
  758.     DWindow::ResizeWin();
  759.     //if (fDlog) fDlog->ViewRect( gRichDocRect);
  760. }
  761.  
  762. Nlm_Boolean DChildDlogDoc::IsMyAction(DTaskMaster* action) 
  763. {
  764.     char buf[512];
  765.  
  766.     if (action->Id() >= DControlStyle::kControlKindStart
  767.         && action->Id() <= DControlStyle::kControlKindEnd)
  768.         {
  769.         switch (action->Id()) {
  770.         
  771.             case DControlStyle::kFileChooser:
  772.                 {
  773.                 DFileCStyle* cs= (DFileCStyle*) ((DView*)action)->fKind;
  774.                 const char* name= DFileManager::GetInputFileName( NULL, NULL);
  775.                 if (name) cs->fNamebox->SetTitle( (char*)name);
  776.                 }
  777.                 return true;
  778.                 
  779.             //kButton, kSubmitButton,  kResetButton,     kRadioButton, kCheckBox,
  780.              //kPopup, kPrompt,     kEditText,     kDialogScrollText,
  781.           //kPasswordText, 
  782.             default:
  783.                 //dlog checkboxes, radios, edittext, etc all call here when actioned!
  784.                 //Message(MSG_OK,"DControlStyle::message not ready.");
  785.                 return true;
  786.             }
  787.         }
  788.         
  789.     switch(action->Id()) {
  790.     
  791.         case cOKAY:
  792.             this->OkayAction();
  793.             fOkay= true;
  794.             // fall thru to next case
  795.         case cCANC: 
  796.             fModal= false;
  797.             this->Close(); 
  798.             return true;
  799.  
  800.         case DApplication::kUndo:
  801.             Message(MSG_OK,"DChildDlogDoc::Undo not ready.");
  802.             return true;
  803.         case DApplication::kCut:
  804.             Message(MSG_OK,"DChildDlogDoc::Cut not ready.");
  805.             //this->CutText(); 
  806.             return true;
  807.             
  808.         case DApplication::kCopy: {
  809.             Message(MSG_OK,"DChildDlogDoc::Copy not ready.");
  810.         }
  811.             return true;
  812.             
  813.         case DApplication::kPaste:
  814.             Message(MSG_OK,"DChildDlogDoc::Paste not ready.");
  815.             //this->PasteText(); 
  816.             return true;
  817.         case DApplication::kClear:
  818.             Message(MSG_OK,"DChildDlogDoc::Clear not ready.");
  819.             //this->ClearText(); 
  820.             return true;
  821.         case DApplication::kSelectAll:
  822.             Message(MSG_OK,"DChildDlogDoc::Select all not ready.");
  823.             //if (fDlog) fDlog->SelectAll();
  824.             //this->SetSelection(0,0,32000,32000); 
  825.             return true;
  826.         default:
  827.             return DWindow::IsMyAction(action);
  828.         }
  829. }
  830.  
  831.  
  832. #ifdef WIN_MOTIF
  833. #include <ncbiwin.h>
  834. #include <ncbiport.h>
  835. extern Display* Nlm_currentXDisplay;
  836. extern Window   Nlm_currentXWindow;
  837. #endif
  838.  
  839. void DChildDlogDoc::Open()
  840. {
  841.     this->CalcWindowSize();
  842.     fDlog->ReadyToOpen();
  843.     DWindow::Open();
  844. #ifdef WIN_MOTIF
  845.     //fDlog->SendBehind();
  846.     fDlog->Select();
  847.     XLowerWindow( Nlm_currentXDisplay, Nlm_currentXWindow); // make this a DView method?
  848. #endif
  849. }
  850.  
  851.  
  852.  
  853.